/*******************************************************************************
 Platform : AVR mega16学习板（www.iccavr.com）
 Project  : 实验一：8种LED点亮模式
 Clock F  : 3.6864M
 Software : ICCAVR7.14C
 Author   : 林夕依然
 Version  : 08.11.22
 Updata   : 09.02.25  模块化
 09.04.28  增加了proteus仿真模型，调试通过。
 comments :
 1、以学习板八个LED灯为硬件电路,JP7短路块需装上
 2、练习简单延时函数的编制
 3、AVR单片机端口寄存器的使用及理解
 4、练习程序模块化，结构化的书写
 5、单片机休眠模式练习
 6、8种LED点亮模式
 *******************************************************************************/
#include <avr/io.h>

#include <avr/iom16.h>

#include <avr/interrupt.h>
#include <util/delay.h>

/*
 * old
 * 4 -> d3
 * 5 -> d4
 * 6 -> d6
 *
 * new:
 * 4 -> a4
 * 5 -> a5
 * 6 -> a6
 */

#include "led.h"

volatile unsigned int timer_counter[8];
volatile unsigned int light_on_flag[8];
volatile unsigned int max;

void set_timer() {
	TCNT1H = 0Xff;
	TCNT1L = 0Xf0;

	// time out = 8000000/128/16= 1/3906.25 second

}

void wdt_reset() {
	asm("WDR;\n");
}
ISR( TIMER1_OVF_vect)

{

	int i1;
	int light=0x00;
	//reset the interrupt
	set_timer();
	wdt_reset();
	for (i1 = 0; i1 < 8; i1++) {

		timer_counter[i1]++;


		if (timer_counter[i1] > max*(i1+1)) {

			if (light_on_flag[i1] == 0) {
				light_on_flag[i1] = 1;

			} else {

				light_on_flag[i1] = 0;
			}
			timer_counter[i1] = 0;
			//max+=500;
		}

		if(light_on_flag[i1] ==1){
			light  |= _BV(i1);
		}


	}//end for
	PORTB=~light;

}

void timer_init() {
	TCCR1B = 0X04; // 256 clock
	TIMSK |= 1 << 2; // time1 interrupt enable

}

void sleep() {
	asm("sleep;\n");
}
int main(void) {
	//Initialize all port, set port B to output
	int i1;
	sei();
	/* enable global interrupts */DDRA = 0X00; //端口上拉输入
	PORTA = 0XFF;
	DDRB = 0xFF; //端口输出
	PORTB = 0xFF; //输出高电平，LED熄灭
	DDRC = 0X00;
	PORTC = 0XFF;
	DDRD = 0X00;
	PORTD = 0XFF;

	// 2.1 s to reset
	WDTCR = (1 << WDTOE) | (1 << WDE) | (1 << WDP2) | (1 << WDP1) | (1 << WDP0);

	max = 500;
	timer_init();

	for (i1 = 0; i1 < 8; i1++) {
		light_on_flag[i1] = 0; //off
		timer_counter[i1] = 0;
	}
	set_timer();

	while (1) {
		MCUCR = 0x40; //空闲模式，CPU占用100%
		//MCUCR=0x50;          //ADC噪声抑制模式，CPU占用100%
		//MCUCR=0x60;          //掉电模式，CPU占用80%
		//MCUCR = 0x70; //省电模式，CPU占用4%
		//MCUCR=0xE0;          //Standby模式，CPU占用80%
		//MCUCR = 0xF0; //扩展Standby模式，CPU占用4%
		//asm("sleep\n");
		//CPU休眠指令
		sleep();
	}
}
